package com.gitee.sop.layui.adminserver.module.background.develop.util;

import com.gitee.sop.layui.adminserver.module.background.develop.entity.SysFunction;
import com.gitee.sop.layui.adminserver.module.background.develop.vo.SysFunctionTreeTableVo;
import com.gitee.sop.layui.adminserver.module.base.bo.ZTreeNode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: huwei
 * @date: 2020/3/12 15:09
 * @version: 1.0.0
 */
public class SysFunctionUtil {

    /**
     * 将功能转换为树表格
     *
     * @param sysFunctionList 功能列表
     * @return
     */
    public static List<SysFunctionTreeTableVo> toSysFunctionTreeTableVo(List<SysFunction> sysFunctionList, int maxId) {

        List<SysFunctionTreeTableVo> res = new ArrayList<>(sysFunctionList.size());

        //缓存map ，用于存放树形key与id的映射，方便子节点，找到父节点id
        Map<String, Integer> nodeToId = new HashMap<>(res.size());

        for (SysFunction sysFunction : sysFunctionList) {
            Integer rootId = nodeToId.get(sysFunction.getRootPath());
            if (rootId == null) {
                //创建当前功能的rootPath节点
                SysFunctionTreeTableVo sysFunctionTreeTableVo = createTreeTableVo(sysFunction, ++maxId, 0, sysFunction.getRootPath());
                nodeToId.put(sysFunction.getRootPath(), sysFunctionTreeTableVo.getId());
                res.add(sysFunctionTreeTableVo);

                rootId = sysFunctionTreeTableVo.getId();
            }

            String moduleNameKey = sysFunction.getRootPath() + "." + sysFunction.getModuleName();
            Integer moduleNameId = nodeToId.get(moduleNameKey);
            if (moduleNameId == null) {
                //创建当前功能的module节点
                SysFunctionTreeTableVo sysFunctionTreeTableVo = createTreeTableVo(sysFunction, ++maxId, rootId, sysFunction.getModuleName());
                nodeToId.put(moduleNameKey, sysFunctionTreeTableVo.getId());
                res.add(sysFunctionTreeTableVo);

                moduleNameId = sysFunctionTreeTableVo.getId();
            }

            String classDirKey = moduleNameKey + "." + sysFunction.getClassDir();
            Integer classDirId = nodeToId.get(classDirKey);
            if (classDirId == null) {
                //创建当前功能的classDir 父节点
                SysFunctionTreeTableVo sysFunctionTreeTableVo = createTreeTableVo(sysFunction, ++maxId, moduleNameId, sysFunction.getClassDir());
                nodeToId.put(classDirKey, sysFunctionTreeTableVo.getId());
                res.add(sysFunctionTreeTableVo);

                classDirId = sysFunctionTreeTableVo.getId();
            }

            String classNameKey = classDirKey + "." + sysFunction.getClassName();
            Integer classNameId = nodeToId.get(classNameKey);
            if (classNameId == null) {
                //创建当前功能的class name 节点
                SysFunctionTreeTableVo sysFunctionTreeTableVo = createTreeTableVo(sysFunction, ++maxId, classDirId, sysFunction.getClassName());
                nodeToId.put(classNameKey, sysFunctionTreeTableVo.getId());
                res.add(sysFunctionTreeTableVo);

                classNameId = sysFunctionTreeTableVo.getId();
            }

            //创建当前功能节点
            SysFunctionTreeTableVo sysFunctionTreeTableVo = createTreeTableVo(sysFunction, sysFunction.getId(), classNameId, sysFunction.getFullUri());
            res.add(sysFunctionTreeTableVo);
        }
        return res;
    }

    /**
     * 将功能转换为选择树
     *
     * @param sysFunctionList 功能列表
     * @param maxId           功能当前最大id
     * @return
     */
    public static List<ZTreeNode> toZTreeNode(List<SysFunction> sysFunctionList, int maxId) {

        List<ZTreeNode> res = new ArrayList<>(sysFunctionList.size());

        //缓存map ，用于存放树形key与id的映射，方便子节点，找到父节点id
        Map<String, Integer> nodeToId = new HashMap<>(res.size());

        for (SysFunction sysFunction : sysFunctionList) {
            Integer rootId = nodeToId.get(sysFunction.getRootPath());
            if (rootId == null) {
                //创建当前功能的rootPath节点
                ZTreeNode zTreeNode = createZTreeNode(++maxId, 0, sysFunction.getRootPath());
                nodeToId.put(sysFunction.getRootPath(), zTreeNode.getId());
                res.add(zTreeNode);

                rootId = zTreeNode.getId();
            }

            String moduleNameKey = sysFunction.getRootPath() + "." + sysFunction.getModuleName();
            Integer moduleNameId = nodeToId.get(moduleNameKey);
            if (moduleNameId == null) {
                //创建当前功能的module节点
                ZTreeNode zTreeNode = createZTreeNode(++maxId, rootId, sysFunction.getModuleName());
                nodeToId.put(moduleNameKey, zTreeNode.getId());
                res.add(zTreeNode);

                moduleNameId = zTreeNode.getId();
            }

            String classDirKey = moduleNameKey + "." + sysFunction.getClassDir();
            Integer classDirId = nodeToId.get(classDirKey);
            if (classDirId == null) {
                //创建当前功能的classDir 父节点
                ZTreeNode zTreeNode = createZTreeNode(++maxId, moduleNameId, sysFunction.getClassDir());
                nodeToId.put(classDirKey, zTreeNode.getId());
                res.add(zTreeNode);

                classDirId = zTreeNode.getId();
            }

            String classNameKey = classDirKey + "." + sysFunction.getClassName();
            Integer classNameId = nodeToId.get(classNameKey);
            if (classNameId == null) {
                //创建当前功能的class name 节点
                ZTreeNode zTreeNode = createZTreeNode(++maxId, classDirId, sysFunction.getClassName());
                nodeToId.put(classNameKey, zTreeNode.getId());
                res.add(zTreeNode);

                classNameId = zTreeNode.getId();
            }

            //创建当前功能节点
            ZTreeNode zTreeNode = createZTreeNode(sysFunction.getId(), classNameId, sysFunction.getFullUri());
            res.add(zTreeNode);
        }

        res.add(ZTreeNode.createParent());
        return res;
    }

    /**
     * 生成功能树对象
     *
     * @param sysFunction 功能对象
     * @param id          功能id，因为要将功能构成树状结构，所以功能节点的root、module路径会被提取出来，生成的id是不存在的，所以不能使用功能的真实id
     * @param pid         上级id
     * @param name        菜单名称
     */
    private static SysFunctionTreeTableVo createTreeTableVo(SysFunction sysFunction, int id, int pid, String name) {
        SysFunctionTreeTableVo sysFunctionTreeTableVo = new SysFunctionTreeTableVo();
        sysFunctionTreeTableVo.setId(id).setName(name).setPid(pid);
        if (sysFunction.getClassName().equals(name)) {
            sysFunctionTreeTableVo.setUri(sysFunction.getClassUri()).setUriMethod(sysFunction.getClassUriMethod());
        } else if (sysFunction.getFullUri().equals(name)) {
            sysFunctionTreeTableVo.setName(sysFunction.getFnName()).setArgs(sysFunction.getFnArgs())
                    .setUri(sysFunction.getFnUri()).setUriMethod(sysFunction.getFnUriMethod()).setFullUri(sysFunction.getFullUri())
                    .setPermissionSymbol(sysFunction.getPermissionSymbol()).setStatus(sysFunction.getStatus()).setResultType(sysFunction.getResultType());
        }
        return sysFunctionTreeTableVo;
    }

    private static ZTreeNode createZTreeNode(int id, int pid, String name) {
        return new ZTreeNode(id, pid, name, false);
    }
}
